package com.cndw.kungfu.event;

import java.io.EOFException;
import java.io.IOException;
import java.lang.reflect.Method;

import org.jboss.netty.channel.ExceptionEvent;

import com.cndw.kungfu.comm.AccessClose;
import com.cndw.kungfu.comm.AccessFlag;
import com.cndw.kungfu.comm.AccessInspection;
import com.cndw.kungfu.comm.CrossCommand;
import com.cndw.kungfu.comm.GmCommand;
import com.cndw.kungfu.comm.LocalCommand;
import com.cndw.kungfu.config.ConstantsConfig;
import com.cndw.kungfu.config.ConstantsSystem;
import com.cndw.kungfu.ext.LanguageLib;
import com.cndw.kungfu.ext.LogUtil;
import com.cndw.kungfu.model.Context;
import com.cndw.rpg.annotation.UnAuth;
import com.cndw.rpg.exception.StopExecException;
import com.cndw.rpg.framework.ResponseMessage;
import com.cndw.rpg.framework.Session;
import com.cndw.rpg.framework.business.SimpleRequestHandler;

/**
 * 业务处理环节重写
 * 
 * @author fantadust [9677889@qq.com]
 * @date 2011-10-21 上午11:23:51
 */
public class RequestHandler extends SimpleRequestHandler {


	@Override
	public void beforeLogin(Session session) {
		super.beforeLogin(session);

	}

	@Override
	public void beforeExecute(Session session) throws StopExecException {

		int errType = 0;
		String errMessage = null;

		if (ConstantsConfig.isSysClosed() && !AccessInspection.passOnColsed(session)) {
			// 关服情况下.允许gm帐号或者gmIP访问游戏
			errType = -1;
			errMessage = LanguageLib.get("comm.sys.close");
		} else if (ConstantsSystem.isErrDB()) {
			errType = -2;
			errMessage = LanguageLib.get("comm.sys.dberr");
		} else if (AccessInspection.isForbidIp(session.getRemoteAddress())) {
			errType = -3;
			errMessage = LanguageLib.get("comm.sys.iperr");
		} else if (AccessInspection.checkAccount(session.getUid())) {
			errType = -4;// 封号情况下 gmip可以登录
			errMessage = LanguageLib.get("comm.sys.account");
		} else if (ConstantsSystem.getCloseState() > 0 && !AccessInspection.passOnColsed(session)) {
			errType = -1;// 服务器执行了停服命令.不是gm帐号不允许再访问
			errMessage = LanguageLib.get("comm.sys.close");
		}

		if (errType < 0) {
			ResponseMessage message = ResponseMessage.errMsg(errMessage);
			write(session, message);
			throw new StopExecException();
		}
	}

	@Override
	public void beforeExecuteByUnpack(Session session, Method method, Object[] params) throws StopExecException {

		if (method.isAnnotationPresent(AccessClose.class) || (ConstantsConfig.getSysAccessFlag() > 0
				&& (method.getDeclaringClass().isAnnotationPresent(AccessFlag.class)
						&& (ConstantsConfig.getSysAccessFlag() & method.getDeclaringClass().getAnnotation(AccessFlag.class).value()) > 0 || method
						.isAnnotationPresent(AccessFlag.class) && (ConstantsConfig.getSysAccessFlag() & method.getAnnotation(AccessFlag.class).value()) > 0))) {
			
			ResponseMessage message = ResponseMessage.errMsg(LanguageLib.get("comm.err.close"));
			write(session, message);
			throw new StopExecException();
		}

		//log.info(session.getAccountName() + "|"+method.getDeclaringClass().getSimpleName() + ":" +method.getName());

		boolean isPass = true;
		if (method.isAnnotationPresent(LocalCommand.class) && !ConstantsConfig.isLocalHost()) {
			LogUtil.getSysErr().error("LocalCommand err  ip:" + session.getRemoteAddress());
			isPass = false;
		} else if (method.isAnnotationPresent(GmCommand.class)) {
			if (ConstantsConfig.isLocalHost()) {

			} else if (!AccessInspection.isCrossIp(session) && !method.getDeclaringClass().isAnnotationPresent(CrossCommand.class)) {// 不是大区ip不让访问
				isPass = false;
				LogUtil.getSysErr().error("GmCommand ip err :" + session.getRemoteAddress());
			} else if (!AccessInspection.validateRequest(String.valueOf(params[1]), method.getDeclaringClass().getSimpleName(), method.getName())) {
				LogUtil.getSysErr().error("GmCommand sign err :" + session.getRemoteAddress());
				isPass = false;
			}

		} else if (ConstantsConfig.isSysClosed()) {
			// 关服情况下.不是执行gm命令.也不是gm帐号.不允许访问
			isPass = (method.isAnnotationPresent(UnAuth.class) && AccessInspection.isGmIp(session)) || AccessInspection.isGmAcc(session);
			if (!isPass) {
				ResponseMessage message = ResponseMessage.errMsg(LanguageLib.get("comm.sys.close"));
				write(session, message);
				throw new StopExecException();
			}
		}

		if (!isPass) {
			ResponseMessage message = ResponseMessage.errMsg(LanguageLib.get("comm.err.sign"));
			write(session, message);
			throw new StopExecException();
		}
	}

	@Override
	public void errOnExecute(Session session, Exception e, Method method, Object[] params) {
		if (e instanceof IllegalArgumentException) {
			StringBuilder sb = new StringBuilder();
			if (params.length > 1) {
				for (int i = 1; i < params.length; i++) {
					if (params[i] == null) {
						continue;
					}
					sb.append(params[i].getClass().getSimpleName()).append(':').append(params[i].toString());
				}
			}
			LogUtil.getSysErr().error("arg err on " + method.getDeclaringClass().getSimpleName() + ":" + method.getName() + " acc:" + session.getAccountName() + " ip:"
					+ session.getRemoteAddress() + " "+sb.toString());
			
		}else {
			e.printStackTrace();
			LogUtil.getSysErr().error("execute err on " + method.getDeclaringClass().getSimpleName() + ":" + method.getName() + " acc:" + session.getAccountName() + " ip:"
					+ session.getRemoteAddress());
		}
		
		
		
	}

	@Override
	public void errOnMessageReceived(Session session, Exception ex) {
		if (ex instanceof EOFException) {
			LogUtil.getSysErr().error("errOnMessageReceived acc:" + session.getAccountName() + " ip:" + session.getRemoteAddress());
		} else {
			ex.printStackTrace();
			LogUtil.getSysErr().error("err on  acc:" + session.getAccountName() + " ip:" + session.getRemoteAddress());
		}
	}

	@Override
	public void executeOnChannelClosed(Session session) {

		if (session != null && session.isLogin()) {
			Context.getSceneServer().offLine(session);
		}

	}

	@Override
	public void errOnCaughtException(Session session, ExceptionEvent e) {
		// if (e.getChannel().isOpen()) {
		// e.getChannel().close();
		// }
	}

	private void write(Session session, ResponseMessage message) {
		if (session != null && session.getChannel() != null && session.getChannel().isConnected()) {
			try {
				session.getChannel().write(message.serialize());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
